package com.laysonx.easy.invoke.support;

import com.alibaba.fastjson.JSONObject;
import lombok.Data;

import java.io.*;
import java.util.List;

@Data
public class InvokeBody {

    private String target;

    private String name;

    private String method;

    private List<String> paramTypes;

    private List<Object> paramValues;

    public Class<?>[] getMethodParamClass() throws ClassNotFoundException {
        Class<?>[] result = new Class[paramTypes.size()];
        if (paramTypes == null && paramTypes.size() == 0) {
            return result;
        }

        Integer i = 0;
        for (String paramType : paramTypes) {
            Class<?> paramClass = Class.forName(paramType);
            result[i] = paramClass;
            i++;
        }

        return result;
    }


    public Object[] getMethodParam() throws ClassNotFoundException, IOException {
        Object[] result = new Object[paramValues.size()];
        Class<?>[] methodParamClass = getMethodParamClass();
        if (methodParamClass.length != paramValues.size()) {
            throw new RuntimeException("参数数量不匹配");
        }

        int i = 0;
        for (Object paramValue : paramValues) {
            Class<?> paramClass = methodParamClass[i];

            Object value = null;

            if(isBasicObjectType(paramClass)){
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(baos);
                oos.writeObject(paramValue);
                oos.flush();
                oos.close();
                InputStream is = new ByteArrayInputStream(baos.toByteArray());
                value = JSONObject.parseObject(is, paramClass);
            }else{
                JSONObject jsonObject = JSONObject.parseObject((String) paramValue);
                value = JSONObject.toJavaObject(jsonObject, paramClass);
            }

            result[i] = value;

        }

        return result;
    }

    private Boolean isBasicObjectType(Class<?> paramClass) {
        String name = paramClass.getName();
        Boolean result = false;
        if ("java.lang.String".equals(name) ||
                "java.lang.Byte".equals(name) ||
                "java.lang.Short".equals(name) ||
                "java.lang.Integer".equals(name) ||
                "java.lang.Long".equals(name) ||
                "java.lang.Float".equals(name) ||
                "java.lang.Double".equals(name) ||
                "java.lang.Boolean".equals(name) ||
                "java.lang.Character".equals(name) ||
                "java.util.List".equals(name) ||
                "java.util.Set".equals(name) ||
                "java.util.Array".equals(name)) {

            result = true;
        }

        return result;
    }

}
